package itpenguin.portal;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.apache.commons.lang3.time.DateUtils;

@SuppressWarnings("serial")
public class UpdateServlet extends HttpServlet {

	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		List<Map<String, Object>> travelArticles = null;
		List<Map<String, Object>> reviewArticles = null;
		
		XMLInputFactory factory = XMLInputFactory.newInstance();
		travelArticles = getFeeds(factory, new URL("http://travel.it-penguin.com/feeds/posts/default/?max-results=5"));
		reviewArticles = getFeeds(factory, new URL("http://review.it-penguin.com/feed/5"));
		
		StringWriter sw = new StringWriter();
		ServletResponse wrapRes = makeDummyResponse(resp, sw);
		
		req.setAttribute("travelArticles", travelArticles);
		req.setAttribute("reviewArticles", reviewArticles);
		req.setAttribute("isMobile", false);
		
		RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/portal.jsp");
		rd.include(req, wrapRes);
		PortalServlet.content = sw.toString();
		
		sw = new StringWriter();
		wrapRes = makeDummyResponse(resp, sw);
		req.setAttribute("isMobile", true);
		rd.include(req, wrapRes);
		PortalServlet.mobileContent = sw.toString();
		
		PortalServlet.published= new Date();
		
	}

	private List<Map<String, Object>> getFeeds(
			XMLInputFactory factory, URL url) throws IOException,
			ServletException {
		
		final QName REL = new QName("rel");
		final QName HREF = new QName("href");
		XMLEventReader r;
		List<Map<String, Object>> entries = new ArrayList<Map<String,Object>>();
		try {
			Map<String, Object> entry = null;
			r = factory.createXMLEventReader(url.openStream());
			boolean inEntry = false;
			String lastElementName = "";
			
			while (r.hasNext()) {
				XMLEvent e = r.nextEvent();
				if (e.isStartElement()) {
					StartElement element = (StartElement) e;
					String localPart = element.getName().getLocalPart();
					if ("entry".equals(localPart)) {
						entry = new HashMap<String, Object>();
						entries.add(entry);
						inEntry = true;
					} else if (inEntry) {
						lastElementName = element.getName().getLocalPart();
						if ("link".equals(lastElementName)) {
							if("alternate".equals(element.getAttributeByName(REL).getValue())) {
								entry.put(lastElementName, element.getAttributeByName(HREF).getValue());
							}
							lastElementName = null;
						}
					}
				} else if (e.isCharacters()) {
					if ("title".equals(lastElementName) 
							|| "content".equals(lastElementName)
							|| "link".equals(lastElementName)) {
						Characters ch = (Characters) e;
						entry.put(lastElementName, ch.getData());
					} else if ("published".equals(lastElementName)
							|| "updated".equals(lastElementName)) {
						Characters ch = (Characters) e;
						entry.put(lastElementName, parseDate(ch.getData()));
					}
				} else if (e.isEndElement()) {
					EndElement element = (EndElement)e;
					String localPart = element.getName().getLocalPart();
					if ("entry".equals(localPart)) {
						inEntry = false;
					}
					lastElementName = null;
				}
			}
			
			r.close();
		} catch (XMLStreamException e) {
			throw new ServletException(e);
		} catch (ParseException e) {
			throw new ServletException(e);
		}
		return entries;
	}

	private ServletResponse makeDummyResponse(HttpServletResponse resp,
			final StringWriter sw) {
		return new HttpServletResponseWrapper(resp)
		{

			@Override
			public ServletOutputStream getOutputStream() throws IOException {
				return new ServletOutputStream() {
		            @Override
		            public void write(int b) throws IOException {
		            }
		        };

			}

			@Override
			public PrintWriter getWriter() throws IOException {
				 return new PrintWriter(sw);
			}
			
		};
	}
	
	private static Date parseDate(String dateString) throws ParseException{
		
		if (dateString.endsWith("Z")) {
			dateString = dateString.substring(0, dateString.length() - 1) + "+00:00";
		}
		return DateUtils.parseDate(dateString, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", "yyyy-MM-dd'T'HH:mm:ssZZ");
	}

}
